package vip.web3.admin.utils;

import com.portto.solana.web3.Account;
import com.portto.solana.web3.util.TweetNaclFast;
import com.portto.solana.web3.wallet.*;
import org.bitcoinj.core.Base58;
import org.web3j.crypto.*;

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;

public class SolanaUtils {
    private static final String KEYSTORE_PATH = "/Users/addis/Downloads/";

    public static void main(String[] args) {
        try {
            // generate Mnemonic and keystone File
            Bip39Wallet bip39Wallet = generateBip44Wallet("addis", KEYSTORE_PATH);
            //助记词
            String mnemonic = bip39Wallet.getMnemonic();
            System.out.println("助记词：" + mnemonic);
            byte[] seed = MnemonicUtils.generateSeed(mnemonic, "");
            SolanaBip44 solanaBip44 = new SolanaBip44();
            //M/44H/501H/0H/0H
            byte[] privateKeyFromSeed = solanaBip44.getPrivateKeyFromSeed(seed, DerivableType.BIP44CHANGE);
            TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(privateKeyFromSeed);
            System.out.println("地址0：" + Base58.encode(keyPair.getPublicKey()));
            System.out.println("私钥0：" + Base58.encode(keyPair.getSecretKey()));
            Account account = new Account(keyPair);
            System.out.println("Account地址0：" + account.getPublicKey());
            System.out.println("Account私钥0：" + Base58.encode(account.getSecretKey()));

            System.out.println();
            //M/44H/501H/0H/0H
            //通过助记词生成n个地址及私钥
            //拆解 getPrivateKeyFromSeed(seed, DerivableType.BIP44CHANGE);
            for (int i = 0; i < 10; i++) {
                HdKeyGenerator hdKeyGenerator = new HdKeyGenerator();
                SolanaCoin solanaCoin = new SolanaCoin();
                HdAddress masterAddress = hdKeyGenerator.getAddressFromSeed(seed, solanaCoin);
                HdAddress purposeAddress = hdKeyGenerator.getAddress(masterAddress, solanaCoin.getPurpose(), solanaCoin.getAlwaysHardened());// 44H
                HdAddress coinTypeAddress = hdKeyGenerator.getAddress(purposeAddress, solanaCoin.getCoinType(), solanaCoin.getAlwaysHardened());// 501H
                HdAddress accountAddress = hdKeyGenerator.getAddress(coinTypeAddress, i, solanaCoin.getAlwaysHardened());//0H
                HdAddress changeAddress = hdKeyGenerator.getAddress(accountAddress, 0L, solanaCoin.getAlwaysHardened()); //0H
                Account account1 = new Account(TweetNaclFast.Signature.keyPair_fromSeed(changeAddress.getPrivateKey().getPrivateKey()));
                System.out.println("Account地址" + i + "：" + account1.getPublicKey());
                System.out.println("Account私钥" + i + "：" + Base58.encode(account1.getSecretKey()));
            }
        } catch (CipherException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static Bip39Wallet generateBip44Wallet(String pwd, String dirPath) throws CipherException, IOException {
        File dir = new File(dirPath);
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                throw new RuntimeException("make wallet dir error");
            }
        }
        return Bip44WalletUtils.generateBip44Wallet(pwd, dir);
    }

    public static String generateMnemonicFile(String pwd, String mnemonic, String dirPath) throws CipherException, IOException {
        // make dir
        File dir = new File(dirPath);
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                throw new RuntimeException("make wallet dir error");
            }
        }
        // string to pk
        byte[] entBytes = MnemonicUtils.generateEntropy(mnemonic);
        BigInteger entBigInteger = new BigInteger(entBytes);
        ECKeyPair entEcKeyPair = ECKeyPair.create(entBigInteger);
        return WalletUtils.generateWalletFile(pwd, entEcKeyPair, dir, false);
    }

}
